package com.dreamchaser.demo_springmvc.controller;

import com.dreamchaser.demo_springmvc.entity.Author;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;

/**
 * 一般controller的演示类
 * @author Dreamchaser
 */
//标识其为一个Controller类
@Controller
//在controller类前加@RequestMapping注解，可以为所有方法映射路径加个前缀，比如/getRequest01，它实际的访问路径为/prefix/getRequest01
@RequestMapping("/prefix")
public class TestController {
    //@RequestMapping请求映射，value值是映射路径，method标识请求的方式，如get，post，delete，put等（这里是一个枚举类型）。
    // springmvc会根据value中的路径匹配，如果访问路径和value一致则会执行该方法，
    @RequestMapping(value = "/getRequest01",method = RequestMethod.GET )
    //返回类型可以有以下几种，Object,String，ModelAndView。
    //1.返回类型为Object，需要有相应的转换器才可以解析成对应字符串，可以使用fastjson，或者其他解析的工具，同时要加上@ResponseBody注解
    //2.返回值类型为String，该返回值视为view路径，springmvc会去寻找相应路径的视图返回。
    // 如果不想自动解析，需要直接返回字符串，则加上注解@ResponseBody 注解即可
    //3.返回类型为ModelAndView，该对象需要设置数据和视图路径，返回该对象，SpringMVC会去数据渲染到相应视图后返回（渲染的模板引擎可以自己设置）
    //@RequestParam用于匹配传如参数和方法参数不相等
    public @ResponseBody Author getRequest01(@RequestParam(name = "uname",required = false) String username){
        Author author=new Author(username,18);
        return author;
    }
    //@GetMapping(value = "/getRequest02")效果和@RequestMapping(value = "/getRequest02",method = RequestMethod.GET )一致,是一种简写
    //同时@GetMapping("/getRequest02")这样也是可以的
    @GetMapping(value = "/getRequest02")
    public String  getRequest02(String option){
        if ("视图转发".equals(option)){
            //会解析成视图,其实这就是一种转发，不过转发的是视图而已
            return "/WEB-INF/jsp/login.jsp";
        }else if ("路径转发".equals(option)){
            //转发到/getRequest03/{id}这个路径，是服务器内部的转发，这个操作客户是感受不到的
            return "/getRequest03/1";
        }else if ("重定向".equals(option)){
            //重定向到/getRequest03/{id}这个路径，告知浏览器去访问这个路径，这个操作客户是可以感受到的
            return "redirect:/getRequest03/1";
        }else {
            return "/WEB-INF/jsp/register.jsp";
        }
    }
    //该路径写法可以配合@PathVariable注解将路径上的数据注入到参数当中
    @GetMapping(value = "/getRequest03/{id}")
    //将路径中{id}的部分注入到@PathVariable(name = "id")注解的参数上，如路径为/getRequest03/1，那么参数i的值就为1
    public @ResponseBody String getRequest03(@PathVariable(name = "id") Integer i){
        System.out.println(i);
        return "这是数据，不是路径";
    }
    @GetMapping("/getRequest04" )
    //用map类型也可以接受参数，SpringMVC会把参数都put进入map中，不过得在其前面加上@RequestParam注解
    public ModelAndView getRequest04(@RequestParam Map<String,Object> map){
        ModelAndView mv=new ModelAndView();
        //设置视图的路径
        mv.setViewName("/WEB-INF/jsp/register.jsp");
        //增加数据
        mv.addObject("name","Dreamchaser追梦");
        //添加对象也是可以的，不过要有get和set方法
        mv.addObject("author",new Author("Dreamchaser追梦",21));
        return mv;
    }
    @GetMapping("/getRequest05" )
    //用map类型也可以接受参数，SpringMVC会把参数都put进入map中，不过得在其前面加上@RequestParam注解
    public ModelAndView getRequest05(@RequestParam Map<String,Object> map){
        ModelAndView mv=new ModelAndView();
        //设置视图的路径
        mv.setViewName("/WEB-INF/jsp/register.jsp");
        //增加数据
        mv.addObject("name","Dreamchaser追梦");
        //添加对象也是可以的，不过要有get和set方法
        mv.addObject("author",new Author("Dreamchaser追梦",21));
        return mv;
    }

    @PostMapping("/PostTest01")
    //但是大多数情况非get请求的参数都不会放在路径上都是放在请求体中，如果要获取请求体中的参数，只需在参数前面加上@RequestBody
    public @ResponseBody String DeleteRequest01(@RequestBody Map<String,Object> map){
        return "post类型的请求";
    }
    //Post方式的Mapping
    @PostMapping("/PostTest02")
    //如果你需要HttpServletRequest或者HttpServletResponse，只需再参数中加入即可，SpringMVC会自动检查类型，
    //将此次请求的HttpServletRequest和HttpServletResponse注入其中
    public @ResponseBody String PostRequest02(int i, HttpServletRequest request, HttpServletResponse reponse){
        return "post类型的请求";
    }

}
